home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ultimate Screensaver
/
Ultimate Screen Savers Collection (CMS Distributing) (1996).ISO
/
saver4
/
cmap
/
main.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-08
|
5KB
|
169 lines
#include <afxwin.h>
#include <math.h>
#include "main.h"
/*
This is a screen saver which uses colormap animation, a simple technique
to achieve seemingly complicated motion. The entire source of this
program is provided for your convenience. If you find it useful, I'll
appreciate if you'll send me $10. Send the check to:
CMAP registration
c/o: Sin-Yaw Wang
5878 W. Walbrook Dr.
San Jose, CA 95129
You can also contact me at sinyaw@netcom.com.
*/
/////////////////////////////////////////////////////////////////////////////
// theApp:
// Just creating this application object runs the whole application.
//
CTheApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CMainWindow constructor:
// Create the window with the appropriate style, size, menu, etc.
//
CMainWindow::CMainWindow():
timerid(7), // randomly chosen id for timer
speed(15), // how fast the animation is
cmap(NULL), entry(0), animate(0), cmap_size(0),
PI(acos(0)*2.0), INIT_PHASE(0)
{
// create a rect which covers the whole screen
CRect rect(0, 0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
Create( NULL, NULL, WS_POPUP | WS_VISIBLE, rect);
}
CMainWindow::~CMainWindow()
{
delete cmap;
delete animate;
delete (char *)entry;
KillTimer(timerid);
}
BOOL CMainWindow::OnEraseBkgnd(CDC *dc)
{
CRect rect;
GetClientRect(&rect);
CBrush br;
int i = 0;
// paint 256 rects with decreasing sizes with different colors
int dec = -1 * rect.Height() / 256;
CPalette *oldPal = dc->SelectPalette(cmap, FALSE);
dc->RealizePalette();
while (rect.Height() > 4) {
br.CreateSolidBrush(PALETTEINDEX(i++));
dc->FillRect(&rect, &br);
br.DeleteObject();
rect.InflateRect(dec, dec);
i %= 256;
}
dc->SelectPalette(oldPal, FALSE);
return TRUE;
}
int CMainWindow::OnCreate(LPCREATESTRUCT lpCreate)
{
CWindowDC dc(this);
cmap_size = dc.GetDeviceCaps(SIZEPALETTE);
cmap = new CPalette;
void *data = new char[sizeof(LOGPALETTE) +
cmap_size * sizeof(PALETTEENTRY)];
LOGPALETTE *entry = (LOGPALETTE *) data;
animate = new PALETTEENTRY[cmap_size];
ASSERT(cmap != NULL && data != NULL && animate != NULL);
// smooth the color with cosine value with different phase angle
// this part is magic, you can experiment for different effects
int r = 0, g = 0, b = 0;
double ang = 4.0 * PI / (double) cmap_size;
double rphase = INIT_PHASE;
double gphase = rphase + PI / 2.0;
double bphase = gphase + PI / 2.0;
entry->palVersion = 0x300;
entry->palNumEntries = cmap_size;
for (int i = 0; i < cmap_size; i++) {
entry->palPalEntry[i].peRed = LOBYTE(127 + (int) (cos(rphase) * 127.0));
entry->palPalEntry[i].peGreen = LOBYTE(127 + (int) (cos(gphase) * 127.0));
entry->palPalEntry[i].peBlue = LOBYTE(127 + (int) (cos(bphase) * 127.0));
entry->palPalEntry[i].peFlags = PC_RESERVED;
rphase += ang;
gphase += ang;
bphase += ang;
}
// duplicate the colomap to seed the animation
for (i = 0; i < cmap_size; i++) {
animate[i].peRed = entry->palPalEntry[i].peRed;
animate[i].peGreen = entry->palPalEntry[i].peGreen;
animate[i].peBlue = entry->palPalEntry[i].peBlue;
animate[i].peFlags = PC_RESERVED;
}
VERIFY(cmap->CreatePalette(entry));
VERIFY(SetTimer(timerid, speed, NULL));
return CWnd::OnCreate(lpCreate);
}
void CMainWindow::OnTimer(UINT)
{
// synthesize the next animation colormap and install it
PALETTEENTRY tmp;
int i = 0;
int last = cmap_size - 1;
tmp.peRed = animate[0].peRed;
tmp.peGreen = animate[0].peGreen;
tmp.peBlue = animate[0].peBlue;
for (i = 0; i < last; i++) {
animate[i].peRed = animate[i+1].peRed;
animate[i].peGreen = animate[i+1].peGreen;
animate[i].peBlue = animate[i+1].peBlue;
animate[i].peFlags = PC_RESERVED;
}
animate[i].peRed = tmp.peRed;
animate[i].peGreen = tmp.peGreen;
animate[i].peBlue = tmp.peBlue;
animate[i].peFlags = PC_RESERVED;
CWindowDC dc(this);
CPalette *oldPal = dc.SelectPalette(cmap, FALSE);
dc.RealizePalette();
cmap->AnimatePalette(0, cmap_size, animate);
dc.SelectPalette(oldPal, FALSE);
}
BEGIN_MESSAGE_MAP( CMainWindow, CScreenSaverWindow )
ON_WM_CREATE()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
END_MESSAGE_MAP()
BOOL CTheApp::InitInstance()
{
if (m_hPrevInstance)
return FALSE;
if (*m_lpCmdLine && *m_lpCmdLine == '-' || *m_lpCmdLine =='/') {
m_lpCmdLine++;
if (*m_lpCmdLine == 'c' || *m_lpCmdLine == 'C')
return FALSE;
}
m_pMainWnd = new CMainWindow();
m_pMainWnd->ShowWindow( m_nCmdShow );
m_pMainWnd->UpdateWindow();
return TRUE;
}